package controller;

import java.util.List;

import javax.swing.JPanel;

import modelInterfaces.AbstractModelFactory;
import modelInterfaces.ITest;
import utils.Codes;
import utils.Messages;
import utils.Validations;
import view.ViewRecommendersPanel;
import viewInterfaces.AbstractViewFactory;
import viewInterfaces.IViewTestPanel;
import controllerInterfaces.AbstractControllerFactory;
import controllerInterfaces.IControllerMain;
import controllerInterfaces.IControllerTestsPanel;
import controllerInterfaces.IControllerTestSetup;

/**
 * Controller class for test panel.
 * 
 * @author Andy Cullache
 * @authot Salvador Cortes
 */
public class ControllerTestPanel implements IControllerTestsPanel {

	private IControllerMain myController;
	private IControllerTestSetup controllerTestSetup;
	private IViewTestPanel view;
	
	/**
	 * Default constructor.
	 */
	public ControllerTestPanel(){
		this.view = AbstractViewFactory.getAbstractViewFactory().getViewTestPanel();
		this.view.SetController(this);
	}
	
	/**
	* Sets the main controller as controller of this class.
	* 
	* @param controllerMain      main controller class.
	*/
	@Override
	public void SetMainController(IControllerMain controllerMain) {
		this.myController = controllerMain;
	}
	
	
	/**
	 * Returns the JPanel that represents the view of this controller.
	 * 
	 * @return      panel the view of this controller.
	 */
	@Override
	public JPanel getPanel() {
		return this.view.GetPanel();
	}

	/**
	* Returns the list of available tests, corresponds to the same list that appears in the benchmark panel.
	* 
	* @return      list of available tests.
	*/
	public List<ITest> getTests() {
		return this.myController.getTestList();
	}

	
	/**
	* Loading the list of tests in the view
	* 
	*/
	public void loadTestsToView() {
		this.view.setTestUpdate();
	}

	/**
	* Add a test to the tests list.
	* 
	* @param      tests to add.
	*/
	@Override
	public void addTest(ITest test) {
		this.myController.getTestList().add(test);
		this.myController.StatusProjectModified();
		this.loadTestsToView();
	}

	/**
	* Remove a test to the tests list.
	* 
	* @param      tests to remove.
	*/
	@Override
	public void removeTest(ITest test) {
		this.myController.getTestList().remove(test);
		//this.myController.StatusProjectModified();
	}
	
	/**
	* Instantiates the test configuration controller, sets lists of metric and algorithms to new controller.
	*/
	@Override
	public void startTestSetup() {

		this.controllerTestSetup = AbstractControllerFactory.getAbstractControllerFactory().getControllerTestSetup();
		this.controllerTestSetup.setController(this);
		this.controllerTestSetup.setAlgorithmList(this.myController.getProject().getRecommenderList());
		this.controllerTestSetup.setMetricList(this.myController.getProject().getMetricList());
		this.controllerTestSetup.showView();
	}
	
	/**
	* Creates a view with the values of the test that comes from parameter to be edited.
	* @param      test to edit.
	*/
	@Override
	public void editTestSetup(ITest test) {
		this.controllerTestSetup = AbstractControllerFactory.getAbstractControllerFactory().getControllerTestSetup();
		this.controllerTestSetup.setController(this);
		this.controllerTestSetup.setAlgorithmList(this.myController.getProject().getRecommenderList());
		this.controllerTestSetup.setMetricList(this.myController.getProject().getMetricList());
		this.controllerTestSetup.setTest(test);
		this.controllerTestSetup.showView();
	}
	
	/**
	 * Updates the test list of test panel in view of this controller.
	 */
	public void updateTests(){
		//this.view.setTestUpdate();
		this.myController.StatusProjectModified();
	}

	/**
	 * copy the test that this parameter and adds the list of test, 
	 * the new test has the same values as the original, except the name.
	 * 
	 * @param      test to copy.
	 */
	@Override
	public void copyTest(ITest test) {
		ITest testCopy = AbstractModelFactory.getModelFactory().getTest();
		testCopy.setAlgorithms(test.getAlgorithms());
		testCopy.setMetrics(test.getMetrics());
		testCopy.setResultMap(test.getResultMap());
		testCopy.setEventType(test.getEventType());
		
		boolean nameExist = true; 
		int num = 0;
		while(nameExist){
			num++;
			testCopy.setName("CopyOf_" + test.getName() + num);
			if(Validations.isValidAddTest(this.getTests(),testCopy)){
				nameExist = false;
			}
		}
		addTest(testCopy);
		updateTests();
	}

	
	/**
	 * Block all visual components of panel.
	 * @see ViewRecommendersPanel
	 */	
	public void blockAllComponents()
	{
		this.view.setEnabledAll(false);
	}


	/**
	 * UnBlock all visual components of panel.
	 * @see ViewRecommendersPanel.
	 */	
	public void unBlockAllComponents()
	{
		this.view.setEnabledAll(true);
	}

	
	/**
	 * Get status of DB connection.
	 * @return if true then database connection exists, otherwise, doesn't exist .
	 */
	public boolean getDBConnectedStatus() {
		return myController.getDBConnectedStatus();
	}

	@Override
	public IViewTestPanel GetView() {
		return this.view;
	}
	
}
